<template>
  <div class="mapping-item flex flex-col "
       v-loading="accountLoading|| templateLoading||mappingLoading || saveLoading">
    <div class="mapping-item__header flex justify-between items-center">
      <el-form inline>
        <el-form-item>
          <el-select :placeholder="$t('custom.mapping.pleaseSelect')"
                     v-model="searchForm.integrationCode">
            <el-option v-for="item in integerationCodes"
                       :key="item.name"
                       :label="item.name"
                       :value="item.code">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-select :placeholder="$t('custom.mapping.pleaseSelect')"
                     v-model="searchForm.reportType">
            <el-option v-for="item in softwares"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <MappingTemplatesButton type="edit"
                              hover
                              @click.native="handleOpenTemplateDialog" />
    </div>

    <div class="mapping-item__content flex flex-1 h-0">
      <div class="mapping-item__content__left  flex flex-col ">
        <el-input :placeholder="$t('custom.attendance.record.search.search')"
                  prefix-icon="el-icon-search"
                  @input="accountSearchInput"
                  v-model="searchForm.filterAccountText"></el-input>
        <DragItemText />
        <div class="overflow-auto flex-1">
          <el-tree :data="accounts"
                   ref="leftTree"
                   node-key="id"
                   class="account-tree"
                   :filter-node-method="filterNode"
                   default-expand-all
                   draggable
                   check-on-click-node
                   :expand-on-click-node="false"
                   :allow-drop="allowLeftTree"
                   @node-drag-start="startLeftTreeDrag"
                   @node-drag-end="endLeftTreeDrag"
                   @node-click="handleClickLeftTreeNode"
                   :allow-drag="allowLefttTreeDrag">
            <template v-slot="{ data, node }">

              <div :class="{
                  'account-tree__node':true,
                  [`account-tree__node--${data.status}`]: data.status,
                  'account-tree__node--select':hasSelect(data),
                  'account-tree__node--drop':node.isDrop || hasBackDrop(data,'sourceId'),
                }">
                <span class="account-tree__node--num"
                      v-if="data.acctNum">{{data.acctNum}}&nbsp;</span>
                <span class="account-tree__node--title"> {{data.label}}</span>
              </div>

            </template>
          </el-tree>
        </div>

      </div>
      <div class="mapping-item__content__right flex flex-col">
        <div class="mapping-item__content__right__header flex items-center">
          <div class="flex-1">
            <span class="mapping-item__content__right__header--title">{{$t('custom.mapping.mapTo')}}</span>
            <el-dropdown trigger="click"
                         @command="handleChangeTemplate">
              <span class="el-dropdown-link">
                {{searchForm.accountName}}<i class="el-icon-arrow-down el-icon--right"></i>
              </span>
              <el-dropdown-menu slot="dropdown"
                                class="dropdown-menu">
                <el-dropdown-item v-for="(item,index) in templates"
                                  :key="index"
                                  :class="{'dropdown-menu--active':item.id === searchForm.accountId}"
                                  :command="item">
                  <div class="flex justify-between items-center">
                    <span>{{item.name}}</span>
                    <BuildInTag v-if="!item.modifyFlag" />
                  </div>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
            <el-link style="text-decoration:none"
                     type="info"
                     :underline="false"
                     icon="cuifont icon_link"
                     target="_black"
                     :href="systemTemplate[searchForm.accountId]"
                     v-if="systemTemplate[searchForm.accountName]" />
          </div>

          <el-input :placeholder="$t('custom.attendance.record.search.search')"
                    prefix-icon="el-icon-search"
                    v-model="searchForm.filterMapText"
                    @input="mapSearchInput"
                    class="mapping-item__content__right__header--input">
          </el-input>
          <el-button :icon="sortIcons[treeSort]" @click="changeTreeSort" circle size="mini" style="margin-left: 10px;"></el-button>
        </div>
        <div class="overflow-auto flex-1 mapping-item__content__right__content"
             @mouseenter="onMouseenterRightTree"
             @mouseleave="onMouseleaveRightTree"
             v-if="treeVisible">
          <el-tree :data="mappings"
                   node-key="id"
                   ref="rightTree"
                   class="mapping-tree"
                   default-expand-all
                   draggable
                   check-on-click-node
                   highlight-current
                   :indent="16"
                   :expand-on-click-node="false"
                   @node-drag-end="endRightTreeDrag"
                   @node-drop="rightTreeNodeDrop"
                   @node-drag-over="rightTreeNodeDragOver"
                   :allow-drag="allowRightTreeDrag"
                   :allow-drop="allowRightTree"
                   :filter-node-method="filterNode">
            <template v-slot="{ data,node }">
              <div :class="[
                'mapping-tree__node' ,
                'flex',
                'items-center',
                'justify-between',
                {
                  'mapping-tree__node--drop':data.sourceId != -1 && data.sourceId != -2,
                  'mapping-tree__node--empty': data.sourceId == -2,
                  [`mapping-tree__node--level${node.level}`]:data.sourceId == -1
                }
              ]">
                <span class="mapping-tree__node--title">
                  <span style="font-weight:700"
                        v-if="data.acctNum">{{data.acctNum}}&nbsp;
                  </span>
                  {{data.label}}
                </span>
                <div style="display:flex">
                  <!--   v-model="data.popVisible" -->
                  <el-popover
                              popper-class="mapping_popover"

                              :ref="`formatpopover-${data.id}`"
                              placement="bottom"
                              width="200"
                              @show="showFormatFields(data.id,data)"
                              trigger="click">
                    <div style="font-weight:700;padding:12px">{{$t('custom.calculation')}}</div>
                    <el-divider></el-divider>
                    <div style="padding:12px;display:flex;">
                      <el-select v-model="calculation">
                        <el-option v-for="item in options"
                                   :key="item"
                                   :label="item"
                                   :value="item">
                        </el-option>
                      </el-select>
                      <el-input v-model="calculationValue"
                                type="number"
                                style="margin-left:10px"></el-input>
                    </div>
                    <div style="padding:12px;display:flex;justify-content:flex-end">
                      <el-button size="mini"
                                 @click="clearHander">{{$t('clear')}}</el-button>
                      <el-button size="mini"
                                 @click="okHander(data)"
                                 type="primary">{{$t('ok')}}</el-button>
                    </div>
                    <div slot="reference"
                         @click="openFxHander(data)"
                         style="margin-right:10px">
                      <span v-if="data.calculation&&data.calculationValue">{{`${data.calculation}${data.calculationValue}`}}</span>
                      <el-button type="text"
                                 class="mapping-tree__node--btn cuifont icon_field_formula"
                                 v-if="!(data.calculation&&data.calculationValue)&&data.sourceId != -1 && data.sourceId != -2"></el-button>
                    </div>
                  </el-popover>
                  <el-button type="text"
                             class="cuifont icon_copy mapping-tree__node--btn"
                             @click="handleClone(data,node)"
                             v-if="data.sourceId != -1 && data.sourceId != -2"></el-button>
                  <el-button type="text"
                             class="mapping-tree__node--btn cuifont icon_block"
                             @click="handleDelete(data)"
                             v-if="data.sourceId != -1 && data.sourceId != -2"></el-button>
                </div>
              </div>
            </template>
          </el-tree>
        </div>

        <div class="mapping-item__content__right__btn text-right">
          <el-button size="mini"
                     @click="handleCancel">
            {{$t('custom.workSchedule.template.cancel')}}
          </el-button>
          <el-button size="mini"
                     @click="handleSave"
                     type="primary">
            {{$t('custom.bots.savebtn')}}
          </el-button>
        </div>
      </div>
    </div>

    <ManageAccounts ref="manageAccounts"
                    :optionType="searchForm.reportType"
                    :integrationCode="searchForm.integrationCode"
                    @refreshList="handleSuccess" />

    <el-tree ref="cloneTree"
             v-show="false"
             node-key="id"
             :data="dragTree"></el-tree>
  </div>
</template>

<script>
import { getUUID } from '@/utils'
import DragItemText from './components/drag-item-text'
import {
  accountTreeProps,
  softwares,
  systemTemplate
} from '@/views/modules/mspbots/account-mapping/account-mapping.data'
import BuildInTag from '@/views/modules/mspbots/account-mapping/components/build-in-tag'
import ManageAccounts from './manage-accounts'
import qs from 'qs'
import { eachTree, filter, findNode, findNodeAll, treeMapEach } from '@/utils/helperTree'
import ButtonVessel from '@/components/button-vessel'
import { addClass, hasClass, setStyle } from 'element-ui/lib/utils/dom'
import MappingTemplatesButton from '@/views/modules/mspbots/account-mapping/components/mapping-templates-button'

export default {
  name: 'MappingItem',
  components: {
    DragItemText,
    BuildInTag,
    ManageAccounts,
    MappingTemplatesButton,
    ButtonVessel
  },
  data () {
    return {
      searchForm: {
        reportType: 1
      },
      saveDefault:{
        accountId:'',
        accountName:'',
        reportType: 1,
        integrationCode:''
      },
      accounts: [],
      cloneAccounts: [],
      accountLoading: false,

      templates: [],
      templateLoading: false,

      mappingLoading: false,
      mappings: [],
      mappingsCopy: [],
      treeVisible: true,

      integerationCodes: [],
      integerationCodeLoading: false,

      dragTree: [],
      onCtrl: false,

      saveLoading: false,

      backDragData: [],
      cloneBackDragData: [],

      softwares,
      accountTreeProps,
      systemTemplate,

      dropTree: null,
      overPosition: null,
      dropNode: null,
      popVisible: false,
      options: ['+', '-', '*', '/'],
      calculationValue: '',
      calculation: '',
      mappingId: [],
      cloneMapping: [],
      treeSort: 'normal',
      sortIcons: {
        normal: 'el-icon-minus',
        desc: 'el-icon-top',
        asc: 'el-icon-bottom',
      }
    }
  },
  created () {
     if(sessionStorage.getItem('loginAsUserId')==null && sessionStorage.getItem('loginAsRoleId')==null &&this.$store.state.app.isSwitchTenant==0  ) { 
       this.getDefaultTemplate()
      }
    
    setTimeout(()=>{
       this.getIntegerationCodes()
      .then(firstCode => {
        if (firstCode) {
          this.$set(this.searchForm, 'integrationCode', firstCode)
          if(this.saveDefault.integrationCode&&this.searchForm.integrationCode!==this.saveDefault.integrationCode){
            this.searchForm.integrationCode=this.saveDefault.integrationCode
            this.saveDefault.integrationCode=''
          }
          if(this.saveDefault.reportType&&this.searchForm.reportType!==this.saveDefault.reportType){
            this.searchForm.reportType=this.saveDefault.reportType
            this.saveDefault.reportType=''
          }
        }       
      })
    },500)
   
  },
  beforeMount (){

  },
  mounted () {
    this.bindKeyEvent()
  },
  watch: {
    'searchForm.integrationCode' () {
      this.handleChangeCodeOrType()
    },
    'searchForm.reportType' () {
      this.handleChangeCodeOrType()
    },
    mappings: {
      handler (val) {
        this.mappingId = this.getMapArrId(this.mappings, [])
      },
      deep: true
    },
    'searchForm.accountId' () {
      this.getMappings().then(() => {
        const data = this.getDropNode(this.mappings)
        this.backDragData = data
        this.cloneBackDragData = this._.cloneDeep(data)

        this.draw()
      })
    },
    overPosition (newVal, oldVal) {
      // const { get } = this._
      // const emptyData = {
      //   id: 'empty',
      //   label: 'Empty toggle. Drag items inside.',
      //   sourceId: '-2',
      //   pid: get(this.dropNode, 'data.id')
      // }

      // if (newVal === 'inner' && oldVal !== 'inner') {
      //   this.$refs.rightTree.append({ ...emptyData }, this.dropNode)
      // } else {
      //   this.$refs.rightTree.remove('empty')
      // }
    }

  },

  methods: {
    changeTreeSort () {
      this.treeSort = this.treeSort === 'normal' ? 'asc' : this.treeSort === 'asc' ? 'desc' : 'normal'
      if(!this.mappings)return
      if(this.treeSort==='normal'){
        this.mappings = this._.cloneDeep(this.mappingsCopy)
      }else{
        this.mappings = this.sortTree(this.mappings,this.treeSort)
      }
      this.treeVisible=false
      this.$nextTick(()=>{
        this.treeVisible=true
      })
    },
    sortTree (arr=[],type='desc'){
      return arr.sort((a, b) => {
        const reg = /^\[([a-zA-Z]+)(\d*)([a-zA-Z]*)\](.*)/; 
        const matchA = a.label&&a.label.match(reg);
        const matchB = b.label&&b.label.match(reg);
        if (matchA && matchB) { 
          const numA = parseInt(matchA[2]);
          const numB = parseInt(matchB[2]);
          if(numA===numB&&matchA[3]&&matchB[3]){
            return type==='desc'?matchA[3].localeCompare(matchB[3]):matchB[3].localeCompare(matchA[3]); 
          }else if(numA===numB&&matchA[3]){
            return type==='desc'?1:-1;
          }else if(numA===numB&&matchB[3]){
            return type==='desc'?-1:1;
          }else{
            return type==='desc'?numA - numB:numB - numA;
          }
        } else if (!matchA && !matchB) { 
          return type==='desc'?a.label.localeCompare(b.label):b.label.localeCompare(a.label); 
        } else if (matchA) { 
          return type==='desc'?-1:1; 
        } else { 
          return type==='desc'?1:-1; 
        }
      });
    },
   async getDefaultTemplate(){
     try {
       const params = {
        userId:this.$store.state.user.id
      }
        const {data:res} = await this.$interface.mapping.getDefaultTemplate(params)
         if(res.code!==0) {
          this.$message.success(res.msg)
         } 
        let infoObj = JSON.parse(res.data.value) 
        if(infoObj){       
           this.$set(this.saveDefault, 'reportType', infoObj.reportType )
           this.$set(this.saveDefault, 'integrationCode', infoObj.integrationCode )
           this.$set(this.saveDefault, 'accountId', infoObj.accountId)
           this.$set(this.saveDefault, 'accountName', infoObj.accountName)
        }    
     } catch (error) {}
      
    },
    getMapArrId (data, arr) {
      data && data.map(item => {
        arr.push(item.id)
        if (item.sourceId && item.sourceId !== '-1') {
          arr.push(item.sourceId)
        }
        if (item.children && item.children.length) {
          this.getMapArrId(item.children, arr)
        }
      })
      return arr
    },
    showFormatFields (index, data) {
      data.calculation = this.calculation
      data.calculationValue = this.calculationValue
      this.$forceUpdate()
    },
    clearHander () {
      this.calculation = ''
      this.calculationValue = ''
      this.$forceUpdate()
    },
    okHander (data) {
      data.calculation = this.calculation
      data.calculationValue = this.calculationValue
      data.popVisible = false
      this.$refs[`formatpopover-${data.id}`].doClose()
      this.$forceUpdate()
    },
    openFxHander (currentData) {
      function closePop (data) {
        data.popVisible = false
        if (data.children.length > 0) {
          data.children.forEach(item => {
            closePop(item)
          })
        }
      }
      if (!currentData.popVisible) {
        this.mappings.forEach(item => {
          closePop(item)
        })
      }
      currentData.popVisible = !currentData.popVisible
      this.calculation = currentData.calculation
      this.calculationValue = currentData.calculationValue
    },
    draw () {
      this.$nextTick(() => {
        const elements = document.querySelectorAll('.mapping-tree .el-tree-node__content')
        elements.forEach((element, index) => {
          const hasDropNode = Array.from(element.childNodes).some(node => hasClass(node, 'mapping-tree__node--drop'))

          const hasEmptyDropNode = Array.from(element.childNodes).some(node => hasClass(node, 'mapping-tree__node--empty'))
          if (!hasDropNode && index !== elements.length - 1) {
            setStyle(element, { 'border-bottom': '1px solid #F0F0F0' })
          }

          if (index > 0) {
            const preDropNode = Array.from(elements[index - 1].childNodes).some(node => hasClass(node, 'mapping-tree__node--drop'))

            if (preDropNode && !hasDropNode) {
              setStyle(element, { 'border-top': '1px solid #F0F0F0' })
            }
          }

          if (hasDropNode) {
            addClass(element, 'mapping-tree-node__content')
          }

          if (hasEmptyDropNode) {
            addClass(element, 'mapping-tree-node__content--empty')
          }
        })
      })
    },
    hasSelect (data) {
      return findNode(this.dragTree, node => node.id === data.id)
    },
    hasBackDrop (data, key) {
      return this.cloneBackDragData.some(i => i[key] === data.id)
    },
    async getAccounts () {
      try {
        this.accountLoading = true
        const { get, cloneDeep } = this._
        const { getMappingSourceTree } = this.$interface.mapping
        const { reportType, integrationCode } = this.searchForm

        const params = {
          reportType, integrationCode
        }

        let { data: response } = await getMappingSourceTree(params)

        if (response.code !== 0) {
          throw get(response, 'msg', '')
        }
        this.cloneAccounts = cloneDeep(get(response, 'data', []))

        this.accounts = get(response, 'data', [])
      } catch (error) {
        this.accounts = []
      } finally {
        this.accountLoading = false
      }
    },

    async getMappings () {
      try {
        const { accountId } = this.searchForm
        if (!accountId) {
          return
        }
        this.mappingLoading = true
        this.treeSort = 'normal'
        const { get, cloneDeep } = this._
        const { getMappingTree } = this.$interface.mapping
       
        const params = {
          accountId
        }

        let { data: response } = await getMappingTree(params)
        if (response.code !== 0) {
          throw get(response, 'msg', '')
        }

        this.mappings = get(response, 'data', [])
        this.mappingsCopy = cloneDeep(this.mappings)
        this.accounts = cloneDeep(this.cloneAccounts)
        this.$forceUpdate()

        return
      } catch (error) {
        this.mappings = []
        this.$message.error(error)
      } finally {
        this.mappingLoading = false
      }
    },

    async getTemplates () {
      const emptyTemplate = [{ id: 1, name: 'No data' }]
      try {
        this.templateLoading = true

        const { get, nth } = this._
        const { requstTempList } = this.$interface.mapping
        const { integrationCode, reportType } = this.searchForm
        const params = {
          type: reportType,
          integrationCode
        }

        let { data: response } = await requstTempList(params)

        if (response.code !== 0) {
          throw get(response, 'msg', '')
        }

        this.templates = get(response, 'data', emptyTemplate)

        if (this.templates.length > 0) {
          return nth(this.templates, 0)
        }
      } catch (error) {
        this.templates = emptyTemplate
        this.$message.error(error)
      } finally {
        this.templateLoading = false
      }
    },
    async getIntegerationCodes () {
      try {
        this.integerationCodeLoading = true
        const { get, nth } = this._
        const { getReportIntegration } = this.$interface.mapping

        let { data: response } = await getReportIntegration()

        if (response.code !== 0) {
          throw get(response, 'msg', '')
        }

        this.integerationCodes = get(response, 'data', [])
        if (this.integerationCodes.length > 0) {
          return get(nth(this.integerationCodes, 0), 'code')
        }
      } catch (error) {
        this.integerationCodes = []
        this.$message.error(error)
      } finally {
        this.integerationCodeLoading = false
      }
    },

    handleChangeTemplate (command) {
      if (command.id !== 1) {
        this.searchForm.accountId = command.id
        this.searchForm.accountName = command.name
      }
      //  console.log(sessionStorage.getItem('loginAsUserId'),sessionStorage.getItem('loginAsUserId'));
      //   console.log(sessionStorage.getItem('loginAsRoleId'),sessionStorage.getItem('loginAsRoleId'));
      //   console.log(this.$store.state.app.isSwitchTenant,"this.$store.state.app.isSwitchTenant");
    },

    handleChangeCodeOrType () {
      this.getAccounts()

      this.getTemplates()
        .then(firstTemplate => {
          if (firstTemplate) {
            if (this.searchForm.integrationCode ==="AUTOMATEAGENT") {
              const { name, id } = firstTemplate
              this.$set(this.searchForm, 'accountId', '')
              this.$set(this.searchForm, 'accountName', '')
            } else {
              const { name, id } = firstTemplate
              this.$set(this.searchForm, 'accountId', id)
              this.$set(this.searchForm, 'accountName', name)
            }
            
          }


          let templatesObj = this.templates.find(item=>item.id===this.saveDefault.accountId)
          if(templatesObj) {
            if(this.saveDefault.accountId&&this.searchForm.accountId!==this.saveDefault.accountId){
            this.searchForm.accountId=this.saveDefault.accountId
            this.saveDefault.accountId=''
            }
            if(this.saveDefault.accountName&&this.searchForm.accountName!==this.saveDefault.accountName){
              this.searchForm.accountName=this.saveDefault.accountName
              this.saveDefault.accountName=''
            }
          }
     
        })
    },

    filterNode (value, data) {
      if (!value) {
        return true
      }
      return `${data.label}${data.acctNum}` && `${data.label}${data.acctNum}`.toLowerCase().indexOf(value.toLowerCase()) !== -1
    },

    mapSearchInput (val) {
      this.$refs.rightTree.filter(val)
    },
    accountSearchInput (val) {
      this.$refs.leftTree.filter(val)
    },

    handleOpenTemplateDialog () {
      this.$refs.manageAccounts.dialogVisible = true
    },

    async handleSave () {
      try {
        this.saveLoading = true
        const { get, cloneDeep } = this._
        const { saveMappingTree } = this.$interface.mapping

        const { accountId, integrationCode } = this.searchForm

        const params = {
          accountId,
          integrationCode,
          mapping: this.mappings.map((v,i)=>{
            return {
              ...v,
              sort: i+1
            }})
        }

        let { data: response } = await saveMappingTree(params)

        if (response.code !== 0) {
          throw get(response, 'msg', '')
        }
        this.getMappings().then(() => {
          this.backDragData = this.getDropNode(this.mappings)
          this.cloneBackDragData = cloneDeep(this.backDragData)
          this.draw()
        })
        if(sessionStorage.getItem('loginAsUserId')==null && sessionStorage.getItem('loginAsRoleId')==null && this.$store.state.app.isSwitchTenant==0 ) { 
            this.saveDefaultTemplate()
         }
        this.$message.success(this.$t('success'))
       
      } catch (error) {
        this.$message.error(error)
      } finally {
        this.saveLoading = false
      }
    },
    saveDefaultTemplate(){
        const { reportType, integrationCode,accountId,accountName } = this.searchForm
         const params = {
        userId:this.$store.state.user.id,
        keyword:"account.mapping.default.template",
        value: JSON.stringify( {
          integrationCode:integrationCode,
          reportType:reportType,
          accountId:accountId,
          accountName:accountName
        })
      }
      this.$interface.mapping.saveDefaultTemplate(params).then(({data:res})=>{
        //  console.log(res,"res");
         if(res.code!==0) {
          this.$message.success(res.msg)
         }
      })   
    },   

    handleCancel (double) {
      const { get } = this._
      const dragNodeData = this.getDropNode(this.mappings)

      this.backDragData = this.cloneBackDragData

      this.backDragData.forEach(data => {
        const leftTreeNode = this.$refs.leftTree.getNode({ id: data.sourceId })
        const rightTreeNode = this.$refs.rightTree.getNode({ id: data.id })
        if (!rightTreeNode) {
          this.$refs.rightTree.append(data, get(data, 'pid'))
        }

        this.$set(leftTreeNode.data, 'status', 'disabled')
      })

      dragNodeData.forEach(data => {
        if (!this.hasBackDrop(data, 'id')) {
          const leftTreeNode = this.$refs.leftTree.getNode({ id: data.id })

          this.$set(leftTreeNode.data, 'status', undefined)
          this.$refs.rightTree.remove(data)
        }
      })

      this.draw()
      if (double !== 'double') {
        this.handleCancel('double')
      }
    },

    handleDelete (data) {
      const a = findNodeAll(this.mappings, (record) => {
        return record.sourceId === data.sourceId
      })
      if (a.length === 1) {
        eachTree([data], (record) => {
          const leftTreeNode = this.$refs.leftTree.getNode({ id: record.sourceId })
          if (leftTreeNode && leftTreeNode.data) {
            this.$set(leftTreeNode.data, 'status', undefined)
          } else {
            this.$refs.leftTree.remove(data)
          }
        })
      }
      this.$refs.rightTree.remove(data)
      this.mappingsCopy = this._.cloneDeep(this.mappings)
    },
    handleClone (data, node) {
      data = JSON.parse(JSON.stringify(data))
      data.popVisible = false
      //data.id = getUUID()
      data = treeMapEach(data, {
          conversion: (record) => ({ ...record, id:  getUUID()})
      })
      this.$refs.rightTree.insertAfter(data, node)
      this.$nextTick(() => this.draw())
      this.mappingsCopy = this._.cloneDeep(this.mappings)
    },
    handleSuccess () {
      this.getTemplates()
        .then(firstTemplate => {
          if (firstTemplate) {
            if (this.searchForm.integrationCode ==="AUTOMATEAGENT") {
              const { name, id } = firstTemplate
              this.$set(this.searchForm, 'accountId', '')
              this.$set(this.searchForm, 'accountName', '')
            } else {
              const { name, id } = firstTemplate
              this.$set(this.searchForm, 'accountId', id)
              this.$set(this.searchForm, 'accountName', name)
            }           
          }
        })
    },

    // ===========================  multipe drag tree methods  ==================================== //
    handleClickLeftTreeNode (data) {
      const { find } = this._
      const dragData = this.getDragData(data)

      const notExistData = dragData.filter(i => !find(this.dragTree, ['id', i.id]))
      const existData = dragData.filter(i => find(this.dragTree, ['id', i.id]))
      const idArr = this.getMapArrId(notExistData, [])
      this.dragTree = this.removeRepeat(this.dragTree, idArr)
      if (this.onCtrl) {
        this.dragTree = Array.from(
          new Set(
            [...this.dragTree, ...notExistData].map(i => qs.stringify(i))
          )
        )
          .map(i => qs.parse(i))
          .filter(i => !find(existData, ['id', i.id]))
      } else {
        this.dragTree = [...dragData]
      }
    },
    getDragData (data) {
      const { isPlainObject, cloneDeep, get } = this._
      const cloneData = isPlainObject(data) ? [cloneDeep(data)] : cloneDeep(data)

      return filter(cloneData, (record) => {
        const node = this.$refs.leftTree.getNode(record)
        return !this.hasBackDrop(node, 'sourceId') && !get(node, 'isDrop', false)
      })
    },

    /**
     * Get drop element
     * @return Arrary[]
     */
    getDropNode (data) {
      const { isPlainObject, cloneDeep, get } = this._
      const cloneData = isPlainObject(data) ? [cloneDeep(data)] : cloneDeep(data)

      return (cloneData || []).reduce((result, record) => {
        const { children = [], ...rest } = record
        const sourceId = get(record, 'sourceId', '-1')

        if (sourceId !== '-1') {
          const node = this.$refs.leftTree.getNode({ id: record.sourceId })
          this.$set(node.data, 'status', 'disabled')

          result.push({
            ...rest
          })
        }
        if (children.length > 0) {
          result.push(...this.getDropNode(children))
        }

        return result
      }, [])
    },

    /**
     * Get drag element
     * @return Arrary[]
     */
    getDragNode (data) {
      const { isPlainObject, cloneDeep, get } = this._
      const cloneData = isPlainObject(data) ? [cloneDeep(data)] : cloneDeep(data)

      return cloneData.reduce((result, record) => {
        const { children = [], ...rest } = record
        const status = get(record, 'status')

        if (status !== 'disabled') {
          const node = this.$refs.leftTree.getNode({ id: record.id })
          this.$set(node.data, 'status', 'selected')

          result.push({
            sourceId: record.id,
            ...rest
          })
        }
        if (children.length > 0) {
          result.push(...this.getDragNode(children))
        }

        return result
      }, [])
    },

    startLeftTreeDrag (node, event) {
      const { get } = this._
      if (this.dragTree.length === 0) {
        this.handleClickLeftTreeNode(get(node, 'data'))
      }
      const emptyData = { id: 'root', children: [] }
      this.$refs.cloneTree.append(emptyData)
      const emptyNode = this.$refs.cloneTree.getNode(emptyData)

      this.$refs.rightTree.$emit('tree-node-drag-start', event, { node: emptyNode })
    },
    rightTreeNodeDragOver (draggingNode, dropNode) {
      const { get } = this._
      const position = get(this.$refs.rightTree, 'dragState.dropType')
      this.overPosition = position
      this.dropNode = dropNode
    },
    endLeftTreeDrag (draggingNode, endNode, position, event) {
      this.$refs.rightTree.$emit('tree-node-drag-end', event)
    },
    endRightTreeDrag (draggingNode, endNode, position) {
      const { get } = this._

      const level = get(endNode, 'level')

      const nodeData = get(endNode, 'data')

      if (level === 1 && position !== 'inner') {
        this.$message.warning('Dragging is not allowed here!')
        this.dragTree = []
        setTimeout(() => {
          if (this.cloneMapping.length > 0) {
            this.mappings = this._.cloneDeep(this.cloneMapping)
            this.draw()
          }
        }, 300)
        return false
      }

      if (this.dropTree === 'leftTree') {
        this.dragTree = []

        this.$refs.rightTree.remove('root')
        this.$refs.rightTree.remove('empty')
        return
      }

      if (get(draggingNode, 'data.id') !== 'root') {
        if (position === 'before') {
          this.$set(draggingNode.data, 'pid', get(nodeData, 'pid'))
        }
        if (position === 'after') {
          this.$set(draggingNode.data, 'pid', get(nodeData, 'pid'))
        }
        if (position === 'inner') {
          this.$set(draggingNode.data, 'pid', get(nodeData, 'id'))
        }
      }

      this.dragTree = this.removeRepeat(this.dragTree, this.mappingId)
      this.dragTree.forEach(data => {
        const datasource = treeMapEach(data, {
          conversion: (record) => ({ ...record, sourceId: get(record, 'id') })
        })
        /* ============================= MB-15326 START ============================= */
        if (position === 'before' && level !== 1) {
          this.$refs.rightTree.insertBefore({ ...datasource, pid: get(nodeData, 'pid') }, endNode)
        }
        if (position === 'after' && level !== 1) {
          this.$refs.rightTree.insertAfter({ ...datasource, pid: get(nodeData, 'pid') }, endNode)
        }
        if (position === 'inner' || level === 1) {
          this.$refs.rightTree.append({ ...datasource, pid: get(nodeData, 'id') }, endNode)
        }
        /* ============================= MB-15326 END ============================= */
      })
      this.$refs.rightTree.remove('root')
      this.$refs.rightTree.remove('empty')
      this.cloneMapping = this._.cloneDeep(this.mappings)
      this.mappingsCopy = this._.cloneDeep(this.mappings)
    },
    removeRepeat (arr, idArr) {
      return arr.filter(item => {
        if (item.children && item.children.length) {
          item.children = this.removeRepeat(item.children, idArr)
        }
        return !idArr.includes(item.id)
      })
    },
    // Set the drop data to disabled
    rightTreeNodeDrop () {
      eachTree(this.dragTree, (record) => {
        const leftTreeNode = this.$refs.leftTree.getNode(record)

        this.$set(leftTreeNode.data, 'status', 'disabled')
      })
      this.$refs.rightTree.remove('root')
      this.$refs.rightTree.remove('empty')
      this.dragTree = []
      this.draw()
    },

    allowLeftTree () {
      this.dropTree = 'leftTree'
      return false
    },
    allowRightTree () {
      this.dropTree = 'rightTree'
      return true
    },
    onMouseenterRightTree () {

    },
    onMouseleaveRightTree () {

    },

    allowLefttTreeDrag (node) {
      const { get } = this._
      const status = get(node, 'data.status')
      if (status === 'disabled') {
        return false
      }
      return true
    },
    allowRightTreeDrag (node) {
      const { get } = this._
      const sourceId = get(node, 'data.sourceId', '-1')

      if (get(node, 'data.id') === 'root') {

      } else {
        if (this.hasBackDrop(get(node, 'data'), 'id') || sourceId === '-1') {
          return false
        }
      }

      return true
    },
    bindKeyEvent () {
      document.onkeydown = (event) => {
        if (event.ctrlKey) {
          this.onCtrl = true
        }
      }
      document.onkeyup = () => {
        this.onCtrl = false
      }
    }

  }
}
</script>

<style lang="scss" scoped>
.mapping-item {
  height: 100%;
  &__header {
    padding: 20px;
    box-shadow: 0 0 0 1px #f0f0f0;
    & > .el-form {
      ::v-deep & > .el-form-item {
        margin-bottom: 0;
      }
    }
  }

  &__content {
    &__left {
      width: 40%;
      height: 100%;
      box-shadow: 1px 0 0 0 #f0f0f0;
      .account-tree {
        &__node {
          &--num {
            font-size: 14px;
            font-weight: 700;
          }
          &--title {
            font-size: 16px;
            line-height: 22px;
          }
          &--selected {
            .account-tree__node--num {
              color: #17b3a3;
            }
          }
          &--select {
            .account-tree__node--num {
              color: #17b3a3;
            }
            .account-tree__node--title {
              color: #17b3a3;
            }
          }
          &--disabled {
            color: #c0c4cc;
            cursor: not-allowed;
          }
        }
      }
    }
    &__right {
      width: 60%;
      height: 100%;
      &__header {
        font-size: 16px;
        font-weight: 600;
        color: #404040;
        padding-bottom: 10px;
        &--title {
          padding-right: 40px;
        }
        &--input {
          width: auto;
        }
      }
      &__content {
        padding: 10px 0;

        .mapping-tree {
          background: none !important;
          border: 1px solid #f0f0f0;
          &.el-tree {
            ::v-deep .is-drop-inner {
              & > .el-tree-node__content {
                background-color: #e6f7ff !important;
              }
            }

            ::v-deep .el-tree-node__content {
              height: 38px;
              &:not(.mapping-tree-node__content) {
                background-color: #fff;
                &:hover {
                  background-color: inherit;
                }
              }
              .el-tree-node__expand-icon {
                color: #404040;
                height: 38px;
                width: 38px;
                display: flex;
                justify-content: center;
                align-items: center;
                flex-shrink: 0;
                &.is-leaf {
                  color: transparent;
                }
              }

              &.mapping-tree-node__content {
                height: 38px;
                background: #f2f6fc;
                border-radius: 4px 4px 0px 0px;
                .el-tree-node__expand-icon {
                  height: 38px;
                  width: 38px;
                }
              }
              &.mapping-tree-node__content--empty {
                height: 30px;
                background: rgba(0, 0, 0, 0.05);
                border-radius: 4px;

                .mapping-tree__node {
                  color: rgba(64, 64, 64, 0.5);
                  font-weight: 400;
                  font-size: 14px;
                }
                &:hover {
                  background: rgba(0, 0, 0, 0.05);
                }
                .el-tree-node__expand-icon {
                  height: 30px;
                  width: 30px;
                }
              }

              .mapping-tree__node--btn {
                font-size: 14px;
                color: #606266;
                padding: 0;
              }
              // &:hover {
              //   .mapping-tree__node--btn {
              //     opacity: 1;
              //   }
              // }
            }
          }
          &__node {
            width: 100%;
            font-size: 14px;
            font-weight: 600;
            color: #404040;
            padding-right: 10px;
            &.mapping-tree__node--level1 {
              font-size: 18px;
            }
            &.mapping-tree__node--level2 {
              font-size: 16px;
            }
            &.mapping-tree__node--level3 {
              font-size: 14px;
            }
          }
        }
      }
      &__btn {
        padding-top: 10px;
      }

      ::v-deep .el-tree__drop-indicator {
        position: absolute;
        left: 0;
        right: 0;
        height: 8px!important;
        background-color: #17b3a3;
        &::after{
          content:'';
          position: absolute;
          left: -2px;
          top: 50%;
          width: 12px;
          height: 12px;
          border-radius: 50%;
          border:1px solid #17b3a3;
          background: #fff;
          transform: translateY(-50%);
        }
      }
    }

    &__left,
    &__right {
      padding: 20px;
    }
  }
}
</style>

<style lang="scss" >
.dropdown-menu {
  max-height: 400px;
  overflow-y: auto;
  &--active {
    background-color: #e8f7f6;
    color: #45c2b5;
  }
  &::-webkit-scrollbar {
    width: 5px;
    height: 5px;
  }
  &::-webkit-scrollbar-track {
    background: #efefef;
    border-radius: 2px;
  }
  &::-webkit-scrollbar-thumb {
    background: #bfbfbf;
    border-radius: 10px;
  }
  &::-webkit-scrollbar-thumb:hover {
    background: #888;
  }
}
.mapping_popover {
  padding: 0 !important;
  .el-divider {
    margin: 0;
  }
}

</style>
